import json
import logging
from datetime import datetime, timedelta

from django.db.models import Q, Count
from django.db.models.functions import TruncHour
from django.http import JsonResponse
from rest_framework.views import APIView

from dashboard.models import MonitorTaskExecutionStatus
from hosts_mgr.models import HostList
from hosts_mgr.views import AuthRoleGroupView
from monitor_alert_center.models import AlertLogs, MonitorTask, MonitorGroup
from utils.check_permission import check_permission

logger = logging.getLogger()
# 修改权限
logger.setLevel(logging.INFO)


class MonTaskExecutionStatusView(APIView):
    """获取监控任务执行状态"""

    @check_permission(perms_list=['dashBoard:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        alert_name = data.get("alertName")
        group_name = data.get("groupName")
        type_id = data.get("typeID")
        date_time = data.get("dateTime")
        try:
            query_criteria = Q()
            if alert_name:
                query_criteria &= Q(name__name__contains=alert_name)
            if group_name:
                query_criteria &= Q(group__name__contains=group_name)
            if type_id:
                query_criteria &= Q(type=type_id)
            if date_time:
                query_criteria &= Q(create_time__range=date_time)
            else:
                # 获取当前日期和时间
                current_datetime = datetime.now()
                formatted_current = current_datetime.strftime("%Y-%m-%d %H:%M:%S")

                # 计算12小时前的日期和时间
                twelve_hours_ago = current_datetime - timedelta(hours=24)
                formatted_twelve_hours_ago = twelve_hours_ago.strftime("%Y-%m-%d %H:%M:%S")
                query_criteria &= Q(create_time__range=[formatted_twelve_hours_ago, formatted_current])

            mon_task_execution_status = (MonitorTaskExecutionStatus.objects
                                         .filter(query_criteria)
                                         .values('name__name', 'status', 'create_time'))

            for item in mon_task_execution_status:
                formatted_datetime_str = item['create_time'].strftime("%Y/%m/%d %H:%M")
                item['create_time'] = formatted_datetime_str
        except Exception as e:
            logger.error(e)
            return JsonResponse({"code": 500, "msg": f"获取监控任务执行状态失败：{str(e)}"})
        return JsonResponse({"code": 200, "msg": list(mon_task_execution_status)})


class GetAlertCountView(APIView):
    """获取告警发送量"""

    @check_permission(perms_list=['dashBoard:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        data = json.loads(request.body.decode("utf-8"))
        alert_name = data.get("alertName")
        group_name = data.get("groupName")
        type_id = data.get("typeID")
        date_time = data.get("dateTime")
        type_dict = {'1': '站点检测',
                     '2': '端口检测',
                     '3': '进程检测',
                     '4': '自定义脚本'}
        try:
            query_criteria = Q()
            if alert_name:
                query_criteria &= Q(name__name__contains=alert_name)
            if group_name:
                query_criteria &= Q(mon_group=group_name)
            if type_id and type_id is not None:
                query_criteria &= Q(type=type_dict[str(type_id)])
            if date_time:
                query_criteria &= Q(alert_send_time__range=date_time)
            else:
                # 获取当前日期和时间
                current_datetime = datetime.now()
                formatted_current = current_datetime.strftime("%Y-%m-%d %H:%M:%S")

                # 计算12小时前的日期和时间
                twelve_hours_ago = current_datetime - timedelta(hours=24)
                formatted_twelve_hours_ago = twelve_hours_ago.strftime("%Y-%m-%d %H:%M:%S")
                query_criteria &= Q(alert_send_time__range=[formatted_twelve_hours_ago, formatted_current])

            alert_log_obj = AlertLogs.objects.filter(query_criteria).annotate(
                create_time=TruncHour('alert_send_time')
            ).values(
                'name__name',
                'create_time'
            ).annotate(
                alert_count=Count('name_id')
            ).order_by(
                'create_time',
                'name__name'
            )

            for item in alert_log_obj:
                formatted_datetime_str = item['create_time'].strftime("%Y/%m/%d %H:%M")
                item['create_time'] = formatted_datetime_str
        except Exception as e:
            logger.error(e)
            return JsonResponse({"code": 500, "msg": f"获取告警发送量失败：{str(e)}"})
        return JsonResponse({"code": 200, "msg": list(alert_log_obj)})


class GetNumInfoView(APIView):
    """获取主机、监控、用户数量"""

    @check_permission(perms_list=['dashBoard:list'])  # 直接应用装饰器，无需method_decorator
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        try:
            auth_role_groups = AuthRoleGroupView()
            groups_obj = auth_role_groups.auth(request).values_list('id')
            host_count = HostList.objects.distinct().filter(grouphost__group_id__in=groups_obj).count()

            role_list = request.session.get('role_list')
            mon_group_role_obj = MonitorGroup.objects.filter(sysrolemonitorgroup__role_id__in=role_list).all()
            task_count = MonitorTask.objects.filter(mon_group__in=mon_group_role_obj).count()

            role_list = request.session.get('role_list')
            mon_group_role_obj = MonitorGroup.objects.filter(sysrolemonitorgroup__role_id__in=role_list).all()
            task_obj = MonitorTask.objects.filter(mon_group__in=mon_group_role_obj).all()
            alert_count = AlertLogs.objects.filter(name__in=task_obj).count()
        except Exception as e:
            logger.error(e)
            return JsonResponse({"code": 500, "msg": f"获取主机、监控、用户数量失败：{str(e)}"})
        return JsonResponse(
            {"code": 200, "msg": {"host_count": host_count, "task_count": task_count, "alert_count": alert_count}})
